/**
 * @author ZhangHuihua@msn.com
 * 
 */

var DWZ = {
	// sbar: show sidebar
	keyCode : {
		ENTER : 13,
		ESC : 27,
		END : 35,
		HOME : 36,
		SHIFT : 16,
		TAB : 9,
		LEFT : 37,
		RIGHT : 39,
		UP : 38,
		DOWN : 40,
		DELETE : 46,
		BACKSPACE : 8
	},
	eventType : {
		pageClear : "pageClear", // 用于重新ajaxLoad、关闭nabTab,
									// 关闭dialog时，去除xheditor等需要特殊处理的资源
		resizeGrid : "resizeGrid" // 用于窗口或dialog大小调整
	},
	isOverAxis : function(x, reference, size) {
		// Determines when x coordinate is over "b" element axis
		return (x > reference) && (x < (reference + size));
	},
	isOver : function(y, x, top, left, height, width) {
		// Determines when x, y coordinates is over "b" element
		return this.isOverAxis(y, top, height)
				&& this.isOverAxis(x, left, width);
	},

	pageInfo : {
		pageNum : "pageNum",
		numPerPage : "numPerPage",
		orderField : "orderField",
		orderDirection : "orderDirection"
	},
	statusCode : {
		ok : 200,
		error : 300,
		timeout : 301
	},
	ui : {
		sbar : true
	},
	frag : {}, // page fragment
	_msg : {}, // alert message
	_set : {
		loginUrl : "", // session timeout
		loginTitle : "", // if loginTitle open a login dialog
		debug : false
	},
	msg : function(key, args) {
		var _format = function(str, args) {
			args = args || [];
			var result = str || "";
			for (var i = 0; i < args.length; i++) {
				result = result.replace(new RegExp("\\{" + i + "\\}", "g"),
						args[i]);
			}
			return result;
		}
		return _format(this._msg[key], args);
	},
	debug : function(msg) {
		if (this._set.debug) {
			if (typeof(console) != "undefined")
				console.log(msg);
			else
				alert(msg);
		}
	},
	loadLogin : function() {
		if ($.pdialog && DWZ._set.loginTitle) {
			$.pdialog.open(DWZ._set.loginUrl, "login", DWZ._set.loginTitle, {
						mask : true,
						width : 520,
						height : 260
					});
		} else {
			window.location = DWZ._set.loginUrl;
		}
	},

	/*
	 * json to string
	 */
	obj2str : function(o) {
		var r = [];
		if (typeof o == "string")
			return "\""
					+ o.replace(/([\'\"\\])/g, "\\$1").replace(/(\n)/g, "\\n")
							.replace(/(\r)/g, "\\r").replace(/(\t)/g, "\\t")
					+ "\"";
		if (typeof o == "object") {
			if (!o.sort) {
				for (var i in o)
					r.push(i + ":" + DWZ.obj2str(o[i]));
				if (!!document.all
						&& !/^\n?function\s*toString\(\)\s*\{\n?\s*\[native code\]\n?\s*\}\n?\s*$/
								.test(o.toString)) {
					r.push("toString:" + o.toString.toString());
				}
				r = "{" + r.join() + "}"
			} else {
				for (var i = 0; i < o.length; i++) {
					r.push(DWZ.obj2str(o[i]));
				}
				r = "[" + r.join() + "]"
			}
			return r;
		}
		return o.toString();
	},
	jsonEval : function(data) {
		try {
			if ($.type(data) == 'string')
				return eval('(' + data + ')');
			else
				return data;
		} catch (e) {
			return {};
		}
	},
	ajaxError : function(xhr, ajaxOptions, thrownError) {
		if (alertMsg) {
			alertMsg.error("<div>Http status: " + xhr.status + " "
					+ xhr.statusText + "</div>" + "<div>ajaxOptions: "
					+ ajaxOptions + "</div>" + "<div>thrownError: "
					+ thrownError + "</div>" + "<div>" + xhr.responseText
					+ "</div>");
		} else {
			alert("Http status: " + xhr.status + " " + xhr.statusText
					+ "\najaxOptions: " + ajaxOptions + "\nthrownError:"
					+ thrownError + "\n" + xhr.responseText);
		}
	},
	ajaxDone : function(json) {
		if (json.statusCode == DWZ.statusCode.error) {
			if (json.message && alertMsg)
				alertMsg.error(json.message);
		} else if (json.statusCode == DWZ.statusCode.timeout) {
			if (alertMsg)
				alertMsg.error(json.message || DWZ.msg("sessionTimout"), {
							okCall : DWZ.loadLogin
						});
			else
				DWZ.loadLogin();
		} else {
			if (json.message && alertMsg)
				alertMsg.correct(json.message);
		};
	},

	init : function(pageFrag, options) {
		var op = $.extend({
					loginUrl : "login.html",
					loginTitle : null,
					callback : null,
					debug : false,
					statusCode : {}
				}, options);
		this._set.loginUrl = op.loginUrl;
		this._set.loginTitle = op.loginTitle;
		this._set.debug = op.debug;
		$.extend(DWZ.statusCode, op.statusCode);
		$.extend(DWZ.pageInfo, op.pageInfo);

		jQuery.ajax({
			type : 'GET',
			url : pageFrag,
			dataType : 'xml',
			timeout : 50000,
			cache : false,
			error : function(xhr) {
				alert('Error loading XML document: ' + pageFrag
						+ "\nHttp status: " + xhr.status + " " + xhr.statusText);
			},
			success : function(xml) {
				$(xml).find("_PAGE_").each(function() {
							var pageId = $(this).attr("id");
							if (pageId)
								DWZ.frag[pageId] = $(this).text();
						});

				$(xml).find("_MSG_").each(function() {
							var id = $(this).attr("id");
							if (id)
								DWZ._msg[id] = $(this).text();
						});

				if (jQuery.isFunction(op.callback))
					op.callback();
			}
		});

		var _doc = $(document);
		if (!_doc.isBind(DWZ.eventType.pageClear)) {
			_doc.bind(DWZ.eventType.pageClear, function(event) {
						var box = event.target;
						if ($.fn.xheditor) {
							$("textarea.editor", box).xheditor(false);
						}
					});
		}
	}
};

(function($) {
	// DWZ set regional
	$.setRegional = function(key, value) {
		if (!$.regional)
			$.regional = {};
		$.regional[key] = value;
	};

	$.fn.extend({
		/**
		 * @param {Object}
		 *            op: {type:GET/POST, url:ajax请求地址, data:ajax请求参数列表,
		 *            callback:回调函数 }
		 */
		ajaxUrl : function(op) {
			var $this = $(this);

			$this.trigger(DWZ.eventType.pageClear);

			$.ajax({
						type : op.type || 'GET',
						url : op.url,
						data : op.data,
						cache : false,
						success : function(data,responseStatus,response) {
							var json = DWZ.jsonEval(response.responseText);
							if (json.statusCode == DWZ.statusCode.error) {
								var target = $(document).data("target");
								if(target == "dialog") {
									$.pdialog.closeCurrent();
								}
								if(target == "navTab") {
									navTab.closeCurrentTab();
								}
								if (json.message)
									alertMsg.error(json.message);
							} else {
								$this.html(data).initUI();
								if ($.isFunction(op.callback))
									op.callback(data);
								
							}

							if (json.statusCode == DWZ.statusCode.timeout) {
								if ($.pdialog)
									$.pdialog.checkTimeout();
								if (navTab)
									navTab.checkTimeout();

								alertMsg.error(json.message
												|| DWZ.msg("sessionTimout"), {
											okCall : function() {
												DWZ.loadLogin();
											}
										});
							}

						},
						error : DWZ.ajaxError,
						statusCode : {
							503 : function(xhr, ajaxOptions, thrownError) {
								alert(DWZ.msg("statusCode_503") || thrownError);
							}
						}
					});
		},
		loadUrl : function(url, data, callback) {
			$(this).ajaxUrl({
						url : url,
						data : data,
						callback : callback
					});
		},
		initUI : function() {
			return this.each(function() {
						if ($.isFunction(initUI))
							initUI(this);
					});
		},
		/**
		 * adjust component inner reference box height
		 * 
		 * @param {Object}
		 *            refBox: reference box jQuery Obj
		 */
		layoutH : function($refBox) {
			return this.each(function() {
						var $this = $(this);
						if (!$refBox)
							$refBox = $this.parents("div.layoutBox:first");
						var iRefH = $refBox.height();
						var iLayoutH = parseInt($this.attr("layoutH"));
						var iH = iRefH - iLayoutH > 50 ? iRefH - iLayoutH : 50;

						if ($this.isTag("table")) {
							$this.removeAttr("layoutH").wrap('<div layoutH="'
									+ iLayoutH
									+ '" style="overflow:auto;height:' + iH
									+ 'px"></div>');
						} else {
							$this.height(iH).css("overflow", "auto");
						}
					});
		},
		hoverClass : function(className, speed) {
			var _className = className || "hover";
			return this.each(function() {
						var $this = $(this), mouseOutTimer;
						$this.hover(function() {
									if (mouseOutTimer)
										clearTimeout(mouseOutTimer);
									$this.addClass(_className);
								}, function() {
									mouseOutTimer = setTimeout(function() {
												$this.removeClass(_className);
											}, speed || 10);
								});
					});
		},
		focusClass : function(className) {
			var _className = className || "textInputFocus";
			return this.each(function() {
						$(this).focus(function() {
									$(this).addClass(_className);
								}).blur(function() {
									$(this).removeClass(_className);
								});
					});
		},
		inputAlert : function() {
			return this.each(function() {

						var $this = $(this);

						function getAltBox() {
							return $this.parent().find("label.alt");
						}
						function altBoxCss(opacity) {
							var position = $this.position();
							return {
								width : $this.width(),
								top : position.top + 'px',
								left : position.left + 'px',
								opacity : opacity || 1
							};
						}
						if (getAltBox().size() < 1) {
							if (!$this.attr("id"))
								$this.attr("id", $this.attr("name")
												+ "_"
												+ Math.round(Math.random()
														* 10000));
							var $label = $('<label class="alt" for="'
									+ $this.attr("id") + '">'
									+ $this.attr("alt") + '</label>')
									.appendTo($this.parent());

							$label.css(altBoxCss(1));
							if ($this.val())
								$label.hide();
						}

						$this.focus(function() {
									getAltBox().css(altBoxCss(0.3));
								}).blur(function() {
									if (!$(this).val())
										getAltBox().show().css("opacity", 1);
								}).keydown(function() {
									getAltBox().hide();
								});
					});
		},
		isTag : function(tn) {
			if (!tn)
				return false;
			return $(this)[0].tagName.toLowerCase() == tn ? true : false;
		},
		/**
		 * 判断当前元素是否已经绑定某个事件
		 * 
		 * @param {Object}
		 *            type
		 */
		isBind : function(type) {
			var _events = $(this).data("events");
			return _events && type && _events[type];
		},
		/**
		 * 输出firebug日志
		 * 
		 * @param {Object}
		 *            msg
		 */
		log : function(msg) {
			return this.each(function() {
						if (console)
							console.log("%s: %o", msg, this);
					});
		}
	});

	/**
	 * 扩展String方法
	 */
	$.extend(String.prototype, {
		isPositiveInteger : function() {
			return (new RegExp(/^[1-9]\d*$/).test(this));
		},
		isInteger : function() {
			return (new RegExp(/^\d+$/).test(this));
		},
		isNumber : function(value, element) {
			return (new RegExp(/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/)
					.test(this));
		},
		trim : function() {
			return this.replace(/(^\s*)|(\s*$)|\r|\n/g, "");
		},
		startsWith : function(pattern) {
			return this.indexOf(pattern) === 0;
		},
		endsWith : function(pattern) {
			var d = this.length - pattern.length;
			return d >= 0 && this.lastIndexOf(pattern) === d;
		},
		replaceSuffix : function(index) {
			return this.replace(/\[[0-9]+\]/, '[' + index + ']').replace(
					'#index#', index);
		},
		trans : function() {
			return this.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(
					/&quot;/g, '"');
		},
		encodeTXT : function() {
			return (this).replaceAll('&', '&amp;').replaceAll("<", "&lt;")
					.replaceAll(">", "&gt;").replaceAll(" ", "&nbsp;");
		},
		replaceAll : function(os, ns) {
			return this.replace(new RegExp(os, "gm"), ns);
		},
		replaceTm : function($data) {
			if (!$data)
				return this;
			return this.replace(RegExp("({[A-Za-z_]+[A-Za-z0-9_]*})", "g"),
					function($1) {
						return $data[$1.replace(/[{}]+/g, "")];
					});
		},
		/**
		 * {id内容}  将这种形式转换成id为大括弧中的值的input值
		 */
		replaceTmById : function(_box) {
			var $parent = _box || $(document);
			return this.replace(RegExp("({[A-Za-z_]+[A-Za-z0-9_]*})", "g"),
					function($1) {
						var $input = $parent.find("#"
								+ $1.replace(/[{}]+/g, ""));
						return $input.val() ? $input.val() : $1;
					});
		},
		isFinishedTm : function() {
			return !(new RegExp("{[A-Za-z_]+[A-Za-z0-9_]*}").test(this));
		},
		skipChar : function(ch) {
			if (!this || this.length === 0) {
				return '';
			}
			if (this.charAt(0) === ch) {
				return this.substring(1).skipChar(ch);
			}
			return this;
		},
		isValidPwd : function() {
			return (new RegExp(/^([_]|[a-zA-Z0-9]){6,32}$/).test(this));
		},
		isValidMail : function() {
			return (new RegExp(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/)
					.test(this.trim()));
		},
		isSpaces : function() {
			for (var i = 0; i < this.length; i += 1) {
				var ch = this.charAt(i);
				if (ch != ' ' && ch != "\n" && ch != "\t" && ch != "\r") {
					return false;
				}
			}
			return true;
		},
		isPhone : function() {
			return (new RegExp(/(^([0-9]{3,4}[-])?\d{3,8}(-\d{1,6})?$)|(^\([0-9]{3,4}\)\d{3,8}(\(\d{1,6}\))?$)|(^\d{3,8}$)/)
					.test(this));
		},
		isUrl : function() {
			return (new RegExp(/^[a-zA-z]+:\/\/([a-zA-Z0-9\-\.]+)([-\w .\/?%&=:]*)$/)
					.test(this));
		},
		isExternalUrl : function() {
			return this.isUrl() && this.indexOf("://" + document.domain) == -1;
		}
	});
})(jQuery);

/**
 * You can use this map like this: var myMap = new Map();
 * myMap.put("key","value"); var key = myMap.get("key"); myMap.remove("key");
 */
function Map() {

	this.elements = new Array();

	this.size = function() {
		return this.elements.length;
	}

	this.isEmpty = function() {
		return (this.elements.length < 1);
	}

	this.clear = function() {
		this.elements = new Array();
	}

	this.put = function(_key, _value) {
		this.remove(_key);
		this.elements.push({
					key : _key,
					value : _value
				});
	}

	this.remove = function(_key) {
		try {
			for (i = 0; i < this.elements.length; i++) {
				if (this.elements[i].key == _key) {
					this.elements.splice(i, 1);
					return true;
				}
			}
		} catch (e) {
			return false;
		}
		return false;
	}

	this.get = function(_key) {
		try {
			for (i = 0; i < this.elements.length; i++) {
				if (this.elements[i].key == _key) {
					return this.elements[i].value;
				}
			}
		} catch (e) {
			return null;
		}
	}

	this.element = function(_index) {
		if (_index < 0 || _index >= this.elements.length) {
			return null;
		}
		return this.elements[_index];
	}

	this.containsKey = function(_key) {
		try {
			for (i = 0; i < this.elements.length; i++) {
				if (this.elements[i].key == _key) {
					return true;
				}
			}
		} catch (e) {
			return false;
		}
		return false;
	}

	this.values = function() {
		var arr = new Array();
		for (i = 0; i < this.elements.length; i++) {
			arr.push(this.elements[i].value);
		}
		return arr;
	}

	this.keys = function() {
		var arr = new Array();
		for (i = 0; i < this.elements.length; i++) {
			arr.push(this.elements[i].key);
		}
		return arr;
	}
}
/**
 * set 的对象
 */
function Set() {
	
	var _convertStr = function(str){
		if(this.elements[str] == "json_str") {
			return DWZ.jsonEval(str);
		}else {
			return str;
		}
		
	}
	
	this.elements = {};
	
	this.size = function(){
		var size = 0;
		for(var p in this.elements) {
			if(!this.elements.isPrototypeOf(p)) {
				size++;
			}
		}
		return size;
	}
	this.contains = function(value){
		if(this.elements.hasOwnProperty(value) && !this.elements.isPrototypeOf(value)) {
			return true;
		}else {
			return false;
		}
		
	}
	this.each = function(fun) {
		for(var p in this.elements) {
			if(!this.elements.isPrototypeOf(p)) {
				fun.call(this,_convertStr.call(this,p));
			}
		}
		
	}
	this.filter = function(fun){
		var containers = [];
		for(var p in this.elements) {
			if(fun.call(this,_convertStr(_convertStr.call(this,p))) === true) {
				containers.push(_convertStr.call(this,p));
			}
		}
		return containers;
	}
	this.remove = function(value) {
		delete this.elements[value];	
		
	}
	this.add = function(value){
		if(typeof value == "object") {
			value =  DWZ.obj2str(value);
			this.elements[value] = "json_str";
		}else {
			this.elements[value] = true;
		}
		
	}
	this.addAll = function(sets) {
		for(p in sets) {
			
			if(!sets.isPrototypeOf(p)) {
				if(typeof p == "object") {
					p = DWZ.obj2str(p);
					this.elements[p] = "json_str";
				}
				this.elements[p] = true;
			}
		}
		
	}
}
var StringUtils = {
	isEmpty : function(str){
		return str == null || str === "";
	},
	
	isNotEmpty : function(str){
		return str != null && str !== "";
	},
	
	isBlank : function(str){
		return this.isEmpty($.trim(str));
	},
	
	isNotBlank : function(str){
		return this.isNotEmpty($.trim(str));
	},
	
	encodeURIComponent : function(str){
		str = StringUtils.filterURI(str);
		str = encodeURIComponent(str);
		return str;
	},
	
	encodeURI : function(str){
		str = StringUtils.filterURI(str);
		str = encodeURI(str);
		return str;
	},
	
	filterURI : function(str){
		str = str.replace(/\'/g, "");
		return str;
	}
};
